package org.megha.blog.example.singleton;

import java.util.HashMap;
import java.util.Map;

/**
 * Gives the nth fibonacci number.
 * It memoizes results so that repeated calls are fast.
 *
 * @author megha
 */
public class MemoizedFibonacci {

	// This is the only instance that we will create, ever!
	private static final MemoizedFibonacci SINGLETON_INSTANCE = new MemoizedFibonacci();

	private final Map<Integer, Long> fibonacciPairs = new HashMap<Integer, Long>();

	// constructor is made private so that no one can create an instance of this class.
	private MemoizedFibonacci() {}

	/**
	 * Method to access the only instance of {@link MemoizedFibonacci}.
	 */
	public static MemoizedFibonacci getInstance() {
		return SINGLETON_INSTANCE;
	}

	/**
	 * @return the {@code n}th fibonacci number, starting with 0 for n=0, 1 for n=1
	 */
	public long getNthFibonacci(int n) {
		if (n == 0) return 0;
		if (n == 1) return 1;

		if (fibonacciPairs.containsKey(n)) {
			return fibonacciPairs.get(n);
		}
		long nthFibonacci = getNthFibonacci(n-1) + getNthFibonacci(n-2);
		fibonacciPairs.put(n, nthFibonacci);
		return nthFibonacci;
	}
}
